package com.study.config;

import com.alibaba.fastjson2.JSON;
import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;
import reactor.netty.resources.ConnectionProvider;
import reactor.netty.tcp.TcpClient;

import java.time.Duration;
import java.util.concurrent.TimeUnit;

/**
 * @author zhuzi
 * 2024/11/29 15:40
 */
@Configuration
public class RestAsynConfig {
    /**
     * https://mp.weixin.qq.com/s/KgqbLHiMCURL8WXdwfkJ4A
     *
     * @return
     */
    @Bean
    public WebClient webClient() {
        ConnectionProvider provider = ConnectionProvider.builder("fixed").maxConnections(200) // 最大连接数
                .maxIdleTime(Duration.ofSeconds(60)) // 最大空闲时间
                .maxLifeTime(Duration.ofSeconds(60)) // 最大存活时间
                .pendingAcquireTimeout(Duration.ofSeconds(60)) // 等待获取时间
                .pendingAcquireMaxCount(1000) // 挂起的获取最大计数
                .build();

        TcpClient tcpClient = TcpClient.create(provider)//
                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) // 连接超时时间
                .doOnConnected(connection -> {
                    connection.addHandlerLast(new ReadTimeoutHandler(5000, TimeUnit.MILLISECONDS)); // 读取超时
                    connection.addHandlerLast(new WriteTimeoutHandler(5000, TimeUnit.MILLISECONDS)); // 写入超时
                });

        HttpClient httpClient = HttpClient.from(tcpClient).keepAlive(true) // 启用保持连接
                .responseTimeout(Duration.ofSeconds(10)); // 响应超时时间
        System.out.println(JSON.toJSON(httpClient));
        return WebClient.builder().clientConnector(new ReactorClientHttpConnector(httpClient)).build();
    }
}
